package com.example.springbootdockertest.controller.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生产者
 *
 * @Author liguangcheng
 * @Date 2022/2/16 3:33 下午
 * @Vision 1.0
 **/
public class A {

    public static void main(String[] args) {
        Data2 data = new Data2();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "A").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "B").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "C").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "D").start();
    }
}// 判断等待，业务，通知

// 问题存在，A B C D 4 个线程！ 虚假唤醒
//         if 改为 while 判断
class Data { // 数字 资源类
    private int number = 0;

    //+1
    public synchronized void increment() throws InterruptedException {
        while (number != 0) { //0 // 等待
            this.wait();
        }
        number++;
        System.out.println(Thread.currentThread().getName() + "=>" + number); // 通知其他线程，我+1完毕了
        this.notifyAll();
    }
    //-1

    public synchronized void decrement() throws InterruptedException {
        while (number == 0) { // 1// 等待
            this.wait();
        }
        number--;
        System.out.println(Thread.currentThread().getName() + "=>" + number); // 通知其他线程，我-1完毕了
        this.notifyAll();
    }


}

// 任何一个新的技术，绝对不是仅仅只是覆盖了原来的技术，优势和补充！
// Condition 精准的通知和唤醒线程
class Data2 { // 数字 资源类
    private int number = 0;
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition(); //condition.await(); // 等待 //condition.signalAll(); // 唤醒全部 //+1

    public void increment() throws InterruptedException {
        lock.lock();
        try {// 业务代码
            while (number != 0) { //0 // 等待
                condition.await();
            }
            number++;
            System.out.println(Thread.currentThread().getName() + "=>" + number); // 通知其他线程，我+1完毕了
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }//-1

    public void decrement() throws InterruptedException {
        lock.lock();
        try {
            while (number == 0) { // 1 // 等待
                condition.await();
            }
            number--;
            System.out.println(Thread.currentThread().getName() + "=>" + number); // 通知其他线程，我-1完毕了
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}

